﻿using System.Linq;
using Deepcode.QueryPatterns.Redux.Domain;
using Deepcode.QueryPatterns.Redux.Infra;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NHibernate;
using NHibernate.Linq;

// ReSharper disable InconsistentNaming
namespace Deepcode.QueryPatterns.Redux
{
	[TestClass]
	public class NHibernateAdventureWorksUnitTests
	{
		private ISession _session;

		[TestInitialize]
		public void Init()
		{
			_session = NHibernateHelper.GetSession();
			SqlLogHelper.Init();
		}

		[TestCleanup]
		public void Shutdown()
		{
			NHibernateHelper.CloseSession();
		}

		[TestMethod]
		public void QueryForAllLondonAddresses_Returns434()
		{
			var query = from a in _session.Query<Address>() 
						where a.City == "London" 
						select a;
			
			Assert.AreEqual(434, query.Count());
		}

		[TestMethod]
		public void QueryForAllLondonAddresses_WithSWPostCode_Returns155()
		{
			var query = from a in _session.Query<Address>() 
						where a.City == "London" && a.PostCode.StartsWith("SW") 
						select a;

			Assert.AreEqual(155, query.Count());
		}

		[TestMethod]
		public void QueryForAllAddresses_InProvinceGB_Returns1954()
		{
			var query = from a in _session.Query<Address>() 
						where a.StateProvince.CountryCode == "GB" 
						select a;

			Assert.AreEqual(1954, query.Count());
		}

		[TestMethod]
		public void QueryForAllAddresses_InProvinceGBorFR_Returns3805()
		{
			var query = from a in _session.Query<Address>() 
						where a.StateProvince.CountryCode == "GB" || a.StateProvince.CountryCode == "FR" 
						select a;

			Assert.AreEqual(3805, query.Count());
		}

		[TestMethod]
		public void QueryForAllCustomers_WithHomeAddressInGB_Returns1913()
		{
			var query = from c in _session.Query<Customer>()
						join ca in _session.Query<CustomerAddress>() on c equals ca.Customer
						join a in _session.Query<Address>() on ca.Address equals a
						where ca.Type.Name == "Home" && a.StateProvince.CountryCode == "GB"
						select c;

			Assert.AreEqual(1913, query.Count());
		}

		[TestMethod]
		public void QueryForAllCustomers_WithHomeAddressInGB_AndMoreThanOneOrder_Returns862()
		{
			var query = from c in _session.Query<Customer>()
						join ca in _session.Query<CustomerAddress>() on c equals ca.Customer
						join a in _session.Query<Address>() on ca.Address equals a
						where ca.Type.Name == "Home" && a.StateProvince.CountryCode == "GB" && 
							  c.Orders.Count() > 1
						select c;

			Assert.AreEqual(862, query.Count());
		}

		[TestMethod]
		public void QueryForAllCustomers_WithHomeAddressInGB_AndMoreThan2Orders_AndTotalSpendOver6000_Returns207()
		{
			var query = from c in _session.Query<Customer>()
						join ca in _session.Query<CustomerAddress>() on c equals ca.Customer
						join a in _session.Query<Address>() on ca.Address equals a
						where ca.Type.Name == "Home" && a.StateProvince.CountryCode == "GB" && 
							  c.Orders.Count() > 2 && c.Orders.Sum( ov => ov.Total ) > 6000
						select c;

			Assert.AreEqual(207, query.Count());
		}
	}
}
// ReSharper restore InconsistentNaming
